/*
 *  Copyright (C) 2009  Peter Kist & Jan Ripke
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Manager.h"
#include "State.h"
#include "StateFactory.h"
#include "Producer.h"
#include "LogicHandlerThread.h"

#include <core/Logger.h>
#include <galaxy/Galaxy.h>
#include <mediator/InterMediator.h>

namespace galaxy {
    namespace logic {
        namespace gamestate {


            Manager::Manager(void)
            {
                m_Producer.reset (new Producer(*this));
            }

            Manager::~Manager(void)
            {
            }

            bool Manager::initialize () {
                mediator::InterMediator::registerProducer(*m_Producer);

                //mediator::InterMediator::registerConsumer(*m_CharacterConsumer);
                return true;
            }

            boost::thread * Manager::startManagerThread () {
                boost::shared_ptr<Manager> myself = shared_from_this();
                m_LogicHandlerThread = new LogicHandlerThread (myself);

                boost::thread * thrd = new boost::thread(*m_LogicHandlerThread);
                // give thread a chance to start
                while (m_LogicHandlerThread->m_State != core::Thread::THREAD_STATE_RUNNING) {
                    boost::this_thread::yield();
                }
                return thrd;
            }

            void Manager::terminateThread () {
                m_LogicHandlerThread->m_State = core::Thread::THREAD_STATE_STOP_REQUESTED;
            }

            bool Manager::changeState (logic::State::Name& stateName) {

                LOG_INFO (std::string ("changing state to ") + stateName);

                if (m_CurrentState) {
                    m_CurrentState->terminateState ();
                    LOG_TRACE (std::string("destroy state object ") + m_CurrentState->stateName());
                    m_CurrentState.reset ();
                }

                StatePtr newState = StateFactory::createState (stateName);
                if (! newState) {
                    LOG_ERROR ("Cannot create state " + stateName);
                    return false;
                }

                ManagerPtr manager = shared_from_this ();
                newState->setStateManager (manager);
                newState->setupState ();
                newState->activateState ();

                m_CurrentState = newState;
                return true;
            }

        } // namespace gamestate
    } // namespace logic
} // namespace galaxy
